package in.co.codedoc.user;

import in.co.codedoc.cg.annotations.CacheKey;
import in.co.codedoc.cg.annotations.DBType;
import in.co.codedoc.cg.annotations.ExportedRPCMethod;
import in.co.codedoc.cg.annotations.ExportsRPCMethods;
import in.co.codedoc.cg.annotations.HasProperties;
import in.co.codedoc.cg.annotations.IsCached;
import in.co.codedoc.cg.annotations.IsMappedToJSON;
import in.co.codedoc.cg.annotations.IsMappedToTable;
import in.co.codedoc.cg.annotations.Property;
import in.co.codedoc.encrypt.HashValue;

@IsMappedToJSON
@IsMappedToTable("User")
@HasProperties
({
	@Property(name="id",identity=true),
	@Property(name="version",version=true),
	@Property(name="email",datatype=String.class),
	@Property(name="name",datatype=String.class),
	@Property(name="password",datatypeName="in.co.codedoc.encrypt.HashValue",dbType=DBType.CHAR),
	@Property(name="roleSetId",datatypeName="in.co.codedoc.idcontainer.IdSetId",dbType=DBType.BIGINT)
})
@ExportsRPCMethods
@IsCached
({
	@CacheKey("id"),
	@CacheKey("name"),
	@CacheKey("email"),
	@CacheKey("name,email")
})
@SuppressWarnings("unchecked")
public class User
	extends UserBase
{
	@ExportedRPCMethod(user="<guest>")
	public static Authorization Logon(String id,String password)
	{
		return Logon(id,password,true);
	}
	
	private static Authorization Logon(String id,String password,boolean alterCurrentAuth)
	{
		User user = null; 
			
		if(id.indexOf('@') > 0)
		{
			user = FindByEmail(id);
		}
		else
		{
			user = FindByName(id);
		}
		
		if(user == null)
		{
			if(Logger.logger.isDebugEnabled())
			{
				Logger.logger.debug("User " + id + " not found.");
			}
			return null;
		}
		else
		{
			if(user.GetPassword().equals(new HashValue(password)))
			{
				if(alterCurrentAuth)
				{
					Authorization.SetCurrentAuthorization(user);
					if(Logger.logger.isDebugEnabled())
					{
						Logger.logger.debug
						(
							"Successful logon:" + 
							Authorization.GetCurrentAuthorization()
						);
					}
					
					return Authorization.GetCurrentAuthorization();
				}
				else
				{
					return Authorization.MakeAuthorization(user);
				}
			}
			else
			{
				if(Logger.logger.isDebugEnabled())
				{
					Logger.logger.debug("Passwords for user dont match:" + new HashValue(password) + " VS " + user.GetPassword());
				}
				
				return null;
			}
		}
		
	}
	
	@ExportedRPCMethod(user="<guest>")
	public static boolean ChangePassword(String id,String currentPassword,String newPassword)
	{
		Authorization auth = Logon(id, currentPassword, false);
		
		if(auth != null)
		{
			auth.GetId().Get().SetPassword(new HashValue(newPassword)).Save();
			return true;
		}
		else
		{
			return false;
		}
	}
	
	public boolean HasRole(String roleName)
	{
		Role role = Role.FindByName(roleName);
		
		return GetRoleSetId().Get().Contains(role.GetId());
	}
}
